﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Twodi.Aspect.Interfaces;
using Twodi.Aspect.Args;
using Microsoft.Xna.Framework;
using Twodi.Interfaces;

namespace Twodi.Aspect.Implemented
{
    /// <summary>
    /// Define um componente que possui posição.
    /// </summary>
    public class PositionAspect : AbstractAspect, IPosition
    {
        /// <summary>
        /// Posição do componente.
        /// </summary>
        private Vector2 position;

        /// <summary>
        /// Posição do componente.
        /// </summary>
        public Vector2 Position
        {
            get { return this.position; }
            set
            {
                PositionChangedEventArgs e = new PositionChangedEventArgs(this.position, value);
                this.position = value;
                onPositionChanged(e);
            }
        }

        /// <summary>
        /// Posição do componente representada por um "ponto".
        /// </summary>
        public Point Point
        {
            get { return new Point((int)this.position.X, (int)this.position.Y); }
            set
            {
                PositionChangedEventArgs e = new PositionChangedEventArgs(this.Point, value);
                this.position = new Vector2(value.X, value.Y);
                onPositionChanged(e);
            }
        }

        /// <summary>
        /// Mover componente. O valor é somado a posição atual.
        /// </summary>
        /// <param name="value">Valor a ser somado</param>
        public void Move(Vector2 value)
        {
            this.Position = Vector2.Add(this.Position, value);
        }

        /// <summary>
        /// Mover componente. O valor é somado a posição atual.
        /// </summary>
        /// <param name="value">Valor a ser somado</param>
        public void Move(Point value)
        {
            this.Position = Vector2.Add(this.Position, new Vector2(value.X, value.Y));
        }

        /// <summary>
        /// Mover componente. O valor é somado a posição atual.
        /// </summary>
        /// <param name="x">Valor a ser somado em X.</param>
        /// <param name="y">Valor a ser somado em Y.</param>
        public void Move(int x = 0, int y = 0)
        {
            this.Position = Vector2.Add(this.Position, new Vector2(x, y));
        }

        /// <summary>
        /// Mover componente. O valor é somado a posição atual.
        /// </summary>
        /// <param name="x">Valor a ser somado em X.</param>
        /// <param name="y">Valor a ser somado em Y.</param>
        public void Move(float x = 0, float y = 0)
        {
            this.Position = Vector2.Add(this.Position, new Vector2(x, y));
        }

        /// <summary>
        /// Reseta a posição pro ponto "0,0".
        /// </summary>
        public void Reset()
        {
            this.Position = new Vector2();
        }

        /// <summary>
        /// Evento invocado quando posição for alterada.
        /// </summary>
        public event EventHandler<PositionChangedEventArgs> PositionChanged;

        /// <summary>
        /// Método invocado no momento que a posição é alterada.
        /// </summary>
        /// <param name="e"></param>
        protected void onPositionChanged(PositionChangedEventArgs e)
        {
            if (this.PositionChanged != null)
            {
                this.PositionChanged(this, e);
            }
        }
    }
}
